<template>
  <el-dialog
    title="文件系统"
    class="component-fs-loader"
    :model-value="visible"
    width="840px"
    :before-close="handleClose"
  >
    <div class="fs-loader-container">
      <div class="fs-nav">
        <el-input :value="dirinfo?.current" readonly>
          <template #prepend>当前目录:</template>
          <template #append>
            <el-button
              type="primary"
              icon="el-icon-upload2"
              @click="handleToUp"
            ></el-button>
          </template>
        </el-input>
      </div>
      <div class="fs-content">
        <component
          v-for="item in dirinfo?.list"
          :is="item.isDir ? 'folder' : 'file'"
          :item="item"
          :actived="choosed && item.path === choosed.path"
          :key="item.path"
          @dblclick="handleOpen(item)"
          @click="handleSelect(item)"
        />
      </div>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button
          :disabled="!choosed || !choosable"
          type="primary"
          @click="handleSubmit"
        >
          选 择
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts">
import { defineComponent, SetupContext, ref, computed, watchEffect } from 'vue'
import Folder from './folder.vue'
import File from './file.vue'
import { getDir, getForwardDir, DirResult, FsItem } from '@/api/flow'

export default defineComponent({
  name: 'FsLoader',
  emits: ['selected', 'close'],
  components: {
    Folder,
    File
  },
  props: {
    visible: Boolean,
    type: {
      type: String,
      required: true
    }
  },
  setup(props: any, context: SetupContext) {
    const dirinfo = ref<DirResult>()
    const choosed = ref()
    const formate = (res: DirResult): DirResult => {
      const dirs = res.list.filter(l => l.isDir)
      const files = res.list.filter(l => !l.isDir)
      const arr = [...dirs, ...files]
      return { ...res, list: arr }
    }
    const initDir = async (dir?: string) => {
      const res = await getDir(dir)
      dirinfo.value = formate(res)
    }
    const loadDir = async (dir: string) => {
      if (!dirinfo.value) return
      const res = await getForwardDir((dirinfo.value as DirResult).current, dir)
      dirinfo.value = formate(res)
    }

    watchEffect(() => {
      if (props.visible) {
        initDir()
      } else {
        choosed.value = undefined
        dirinfo.value = undefined
      }
    })

    return {
      handleClose: () => context.emit('close'),
      handleToUp: async () => loadDir('..'),
      handleOpen: (item: FsItem) => {
        loadDir(item.name)
        choosed.value = item
      },
      handleSelect: (item: FsItem) => (choosed.value = item),
      handleSubmit: () => context.emit('selected', choosed.value.path),
      dirinfo,
      choosed,
      choosable: computed(() => {
        if (!choosed.value) return false
        if (props.type === 'dir') return choosed.value.isDir
        if (props.type === 'file') return !choosed.value.isDir
        return false
      })
    }
  }
})
</script>

<style lang="scss" scoped>
.fs-loader-container {
  background: #fff;
  border-radius: 8px;

  .fs-content {
    width: 800px;
    height: 400px;
    overflow-y: auto;
    display: flex;
    flex-flow: row wrap;
  }
}
</style>
